#region Credits
//
// Credit for original work:
// http://www.codeproject.com/Articles/12072/C-NET-DNS-query-component
// Bdev.Net.Dns by Rob Philpott, Big Developments Ltd rob@bigdevelopments.co.uk
// 
#endregion

using System;

namespace Windows.Dns
{
	/// <summary>
	/// An MX (Mail Exchanger) Resource Record (RR) (RFC1035 3.3.9)
	/// </summary>
	
	public class MXRecord : RecordBase, IComparable
	{
		// an MX record is a domain name and an integer preference
		private readonly string		domainName;
		private readonly int		preference;

		// expose these fields public read/only
		public string DomainName	{ get { return domainName; }}
		public int Preference		{ get { return preference; }}
				
		/// <summary>
		/// Constructs an MX record by reading bytes from a return message
		/// </summary>
		/// <param name="pointer">A logical pointer to the bytes holding the record</param>
		internal MXRecord(Pointer pointer)
		{
			preference = pointer.ReadShort();
			domainName = pointer.ReadDomain();
		}

		public override string ToString()
		{
			return string.Format("Mail Server = {0}, Preference = {1}", domainName, preference);
		}

		#region IComparable Members

	    /// <summary>
	    /// Implements the IComparable interface so that we can sort the MX records by their
	    /// lowest preference
	    /// </summary>
	    /// <param name="obj">the other MxRecord to compare against</param>
	    /// <returns>1, 0, -1</returns>
	    public int CompareTo(object obj)
		{
			var mxOther = (MXRecord)obj;

			// we want to be able to sort them by preference
			if (mxOther.preference < preference) return 1;
			if (mxOther.preference > preference) return -1;
			
			// order mail servers of same preference by name
// ReSharper disable StringCompareToIsCultureSpecific
			return -mxOther.domainName.CompareTo(domainName);
// ReSharper restore StringCompareToIsCultureSpecific
		}

		public static bool operator==(MXRecord record1, MXRecord record2)
		{
			if (record1 == null) throw new ArgumentNullException("record1");

			return record1.Equals(record2);
		}
	
		public static bool operator!=(MXRecord record1, MXRecord record2)
		{
			return !(record1 == record2);
		}

		public override bool Equals(object obj)
		{
			// this object isn't null
			if (obj == null) return false;

			// must be of same type
			if (GetType() != obj.GetType()) return false;

			var mxOther = (MXRecord)obj;

			// preference must match
			if (mxOther.preference != preference) return false;
			
			// and so must the domain name
			if (mxOther.domainName != domainName) return false;

			// its a match
			return true;
		}

		public override int GetHashCode()
		{
			return preference;
		}

		#endregion
	}
}
